package com.js.data.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.js.data.common.constant.SymbolConstant;
import com.js.data.common.exception.ApiException;
import com.js.data.system.dto.DictDTO;
import com.js.data.system.dto.DictItemDTO;
import com.js.data.system.entity.SysDict;
import com.js.data.system.entity.SysDictItem;
import com.js.data.system.mapper.SysDictMapper;
import com.js.data.system.query.DictQuery;
import com.js.data.system.service.DictItemService;
import com.js.data.system.service.DictService;
import com.js.data.system.util.DictUtil;
import com.js.data.system.vo.DictItemVO;
import com.js.data.system.vo.DictPageVO;
import com.js.data.system.vo.DictVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 数据字典 服务实现类
 * </p>
 *
 * @author wujj
 * @since 2022-09-06
 */
@Service
public class DictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements DictService {

    @Resource
    private DictItemService dictItemService;


    /**
     * 系统下字典类型列表
     *
     * @param query 查询条件
     * @return CommonResult<IPage < DictPageVO>>
     */
    @Override
    public IPage<DictPageVO> pageDict(DictQuery query) {
        Page<DictPageVO> page = new Page<>(query.getCurrent(), query.getSize());
        return getBaseMapper().selectPageVO(page, query);
    }

    /**
     * 根据keys查找多个字典列表
     *
     * @param keyTypes 类型列表
     * @return HashMap<String, List < DictVO>>
     */
    @Override
    public Map<String, List<DictVO>> listMultipleDict(String keyTypes) {
        return Arrays.stream(keyTypes.split(SymbolConstant.COMMA)).collect(Collectors.toMap(key -> key, DictUtil::getSysDictList, (a, b) -> b, HashMap::new));
    }

    /**
     * 新增字典
     *
     * @param dictDTO 数据字段
     */
    @Override
    public void savDict(DictDTO dictDTO) {
        //校验同级地区名是否重复
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDict::getKeyType, dictDTO.getKeyType());
        if (count(queryWrapper) > 0) {
            throw new ApiException("数据字典已存在");
        }
        SysDict sysDict = new SysDict();
        sysDict.setKeyName(dictDTO.getKeyName());
        sysDict.setKeyType(dictDTO.getKeyType());
        save(sysDict);
    }

    /**
     * 修改字典
     *
     * @param id      主键
     * @param dictDTO 字典
     */
    @Override
    public void editDict(Long id, DictDTO dictDTO) {
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDict::getKeyType, dictDTO.getKeyType())
                .notIn(SysDict::getId, id);
        if (count(queryWrapper) > 0) {
            throw new ApiException("数据字典已存在");
        }
        SysDict sysDictEX = getById(id);
        Optional.ofNullable(sysDictEX).orElseThrow(() -> new ApiException("数据字典不存在"));
        SysDict sysDict = new SysDict();
        sysDict.setKeyName(dictDTO.getKeyName());
        sysDict.setKeyType(dictDTO.getKeyType());
        sysDict.setId(id);
        updateById(sysDict);
        //如果key发生变化,sys_dict表更新dict_key
        if (!sysDictEX.getKeyType().equals(dictDTO.getKeyType())) {
            dictItemService.updateKeyTypeByDictId(id, dictDTO.getKeyType());
        }

    }

    /**
     * 删除字典
     *
     * @param id 主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDict(Long id) {
        removeById(id);
        dictItemService.removeByDictId(id);
    }

    /**
     * 启用数据字典
     *
     * @param id 字典id
     */
    @Override
    public void stateDict(Long id) {
        SysDict sysDict = getById(id);
        Optional.ofNullable(sysDict).orElseThrow(() -> new ApiException("数据字典不存在"));
        String oldState = sysDict.getState();
        if (SymbolConstant.ZERO_STR.equals(oldState)||SymbolConstant.TOW_STR.equals(oldState)) {
            sysDict.setState(SymbolConstant.ONE_STR);
        }
        if (SymbolConstant.ONE_STR.equals(oldState)) {
            sysDict.setState(SymbolConstant.ZERO_STR);
        }

        updateById(sysDict);
    }

    /**
     * 数据字典项
     *
     * @param id 字典id
     * @return List<DictItemVO>
     */
    @Override
    public List<DictItemVO> listDictItem(Long id) {
        return dictItemService.listDictItem(id);
    }

    /**
     * 保存数据字典项
     *
     * @param id    字典id
     * @param items 数据字典项
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDictItem(Long id, List<DictItemDTO> items) {
        SysDict sysDict = getById(id);
        Optional.ofNullable(sysDict).orElseThrow(() -> new ApiException("数据字典不存在"));
        updateById(sysDict);
        String keyType = sysDict.getKeyType();
        dictItemService.removeByDictId(id);
        List<SysDictItem> insertList = new ArrayList<>();
        items.forEach(item -> {
            SysDictItem sysDictItem = new SysDictItem();
            sysDictItem.setDictId(id);
            sysDictItem.setKeyType(keyType);
            sysDictItem.setLabel(item.getLabel());
            sysDictItem.setValue(item.getValue());
            sysDictItem.setSortBy(item.getSortBy());
            insertList.add(sysDictItem);
        });
        dictItemService.saveBatch(insertList);
        DictUtil.delSysDictList(sysDict.getKeyType());
        DictUtil.putSysDict(sysDict.getKeyType());
    }

}
